import Foundation
import CoreMotion
import UniformTypeIdentifiers

struct RawSample: Codable {
    let t: TimeInterval
    let ax: Double
    let ay: Double
    let az: Double
    let wx: Double
    let wy: Double
    let wz: Double
}

struct LinSample: Codable {
    let t: TimeInterval
    let ax_lin: Double
    let ay_lin: Double
    let az_lin: Double
}

final class SensorRecorder: NSObject, ObservableObject {
    private let headphoneMotionManager = CMHeadphoneMotionManager()
    private var timer: Timer?
    private(set) var rateHz: Double = 50
    
    // 连接状态
    @Published var isHeadphoneConnected: Bool = false
    
    private var connectionCheckTimer: Timer?
    
    override init() {
        super.init()
        print("🚀 [初始化1] SensorRecorder 初始化")
        // 设置代理
        headphoneMotionManager.delegate = self
        print("🚀 [初始化] 设置代理完成")
        // 初始化时检查 AirPods 可用性
        checkAirPodsAvailability()
        // 启动轮询检查
        startConnectionPolling()
    }
    
    private var isCheckingConnection = false
    
    private func checkAirPodsAvailability() {
        // 避免重复检查
        guard !isCheckingConnection else {
            print("🔄 [检测] 跳过：正在检查中...")
            return
        }
        
        DispatchQueue.main.async { [weak self] in
            guard let self = self else { return }
            
            print("🔍 [检测] 开始检查 AirPods 连接状态")
            print("   isRunning: \(self.isRunning)")
            
            // 如果正在录制，直接检查 isDeviceMotionActive
            if self.isRunning {
                let isActive = self.headphoneMotionManager.isDeviceMotionActive
                print("   录制中 - isDeviceMotionActive: \(isActive)")
                if self.isHeadphoneConnected != isActive {
                    self.isHeadphoneConnected = isActive
                    print(isActive ? "✅ AirPods 监听活跃" : "⚠️ AirPods 监听中断")
                }
                return
            }
            
            // 如果没在录制，尝试启动来检测
            print("   未录制 - 尝试启动监听来检测...")
            self.isCheckingConnection = true
            
            self.headphoneMotionManager.startDeviceMotionUpdates(to: .main) { motion, error in
                DispatchQueue.main.async {
                    print("📡 [检测] 启动监听回调")
                    
                    // 检查是否启动成功
                    let isActive = self.headphoneMotionManager.isDeviceMotionActive
                    let wasConnected = self.isHeadphoneConnected
                    
                    print("   isDeviceMotionActive: \(isActive)")
                    print("   motion: \(motion != nil ? "有数据" : "无数据")")
                    print("   error: \(error?.localizedDescription ?? "无错误")")
                    
                    self.isHeadphoneConnected = isActive
                    
                    if wasConnected != isActive {
                        if isActive {
                            print("✅ 检测到 AirPods（可获取传感器数据）")
                        } else {
                            print("⚠️ 未检测到 AirPods 或无法获取数据")
                            if let error = error {
                                print("   错误详情: \(error)")
                            }
                        }
                    }
                    
                    // 立即停止测试
                    print("   停止测试性监听")
                    self.headphoneMotionManager.stopDeviceMotionUpdates()
                    self.isCheckingConnection = false
                }
            }
        }
    }
    
    private func authStatusString(_ status: CMAuthorizationStatus) -> String {
        switch status {
        case .notDetermined:
            return "未确定"
        case .restricted:
            return "受限制"
        case .denied:
            return "已拒绝"
        case .authorized:
            return "已授权"
        @unknown default:
            return "未知"
        }
    }
    
    private func startConnectionPolling() {
        print("⏰ [轮询] 启动连接状态轮询检查（每1秒）")
        // 每1秒检查一次 AirPods 连接状态（更频繁以快速响应断开）
        connectionCheckTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
            print("⏰ [轮询] 触发检查")
            self?.checkAirPodsAvailability()
        }
        RunLoop.main.add(connectionCheckTimer!, forMode: .common)
    }
    
    deinit {
        connectionCheckTimer?.invalidate()
    }
    
    // Buffers
    @Published var rawSamples: [RawSample] = []
    @Published var linSamples: [LinSample] = []
    
    // 实时数据展示（用于UI）
    @Published var currentAccX: Double = 0
    @Published var currentAccY: Double = 0
    @Published var currentAccZ: Double = 0
    @Published var currentGyroX: Double = 0
    @Published var currentGyroY: Double = 0
    @Published var currentGyroZ: Double = 0
    @Published var sampleCount: Int = 0
    
    var isRunning: Bool { timer != nil }
    
    func start(rateHz: Double = 50) {
        guard !isRunning else { return }
        self.rateHz = rateHz
        let interval = 1.0 / rateHz
        
        // 检查 AirPods 是否可用
        guard headphoneMotionManager.isDeviceMotionAvailable else {
            print("❌ AirPods 传感器不可用，请确保：")
            print("1. 已连接支持的 AirPods (AirPods 3代、AirPods Pro、AirPods Max)")
            print("2. 已授权运动与健身权限")
            return
        }
        
        rawSamples.removeAll()
        linSamples.removeAll()
        
        print("🔄 正在启动 AirPods 传感器监听...")
        
        // 开始接收 AirPods 传感器数据
        headphoneMotionManager.startDeviceMotionUpdates(to: .main) { [weak self] motion, error in
            guard let self = self else { return }
            
            DispatchQueue.main.async {
                if let error = error {
                    print("❌ AirPods 传感器数据获取失败: \(error.localizedDescription)")
                    print("错误详情: \(error)")
                    self.isHeadphoneConnected = false
                    return
                }
                
                // 检查是否真的开始接收数据
                if !self.headphoneMotionManager.isDeviceMotionActive {
                    print("❌ 无法启动 AirPods 传感器监听，请确保 AirPods 已连接并佩戴")
                    self.isHeadphoneConnected = false
                    return
                }
                
                if let motion = motion {
                    // 首次接收到数据时，确认连接成功
                    if self.rawSamples.isEmpty {
                        self.isHeadphoneConnected = true
                        print("✅ 成功接收 AirPods 传感器数据")
                        let rotationRate = motion.rotationRate
                        print("📱 首个数据 - 陀螺仪: x=\(String(format: "%.4f", rotationRate.x)), y=\(String(format: "%.4f", rotationRate.y)), z=\(String(format: "%.4f", rotationRate.z))")
                    }
                    
                    self.processHeadphoneMotion(motion)
                }
            }
        }
        
        // 使用定时器来保持采样率稳定
        timer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] _ in
            self?.tick()
        }
        RunLoop.current.add(timer!, forMode: .common)
    }
    
    func stop() {
        timer?.invalidate(); timer = nil
        headphoneMotionManager.stopDeviceMotionUpdates()
        latestMotion = nil
        // 不要在这里设置 isHeadphoneConnected = false，让轮询自动检测
    }
    
    private var latestMotion: CMDeviceMotion?
    
    private func processHeadphoneMotion(_ motion: CMDeviceMotion) {
        latestMotion = motion
    }
    
    private func tick() {
        guard let motion = latestMotion else {
            // 如果没有最新数据，打印警告
            if sampleCount == 0 && isRunning {
                print("⚠️ tick() 被调用但没有 motion 数据")
            }
            return
        }
        
        let now = Date().timeIntervalSince1970
        
        // 从 AirPods 获取重力加速度（包含重力）
        let gravity = motion.gravity
        let userAcc = motion.userAcceleration
        
        // 计算总加速度 = 重力 + 用户加速度
        let ax = gravity.x + userAcc.x
        let ay = gravity.y + userAcc.y
        let az = gravity.z + userAcc.z
        
        // 获取陀螺仪数据（旋转速率）
        let rotationRate = motion.rotationRate
        let wx = rotationRate.x
        let wy = rotationRate.y
        let wz = rotationRate.z
        
        // 更新实时数据（用于UI展示）
        currentAccX = ax
        currentAccY = ay
        currentAccZ = az
        currentGyroX = wx
        currentGyroY = wy
        currentGyroZ = wz
        
        // 保存原始数据
        rawSamples.append(RawSample(t: now, ax: ax, ay: ay, az: az, wx: wx, wy: wy, wz: wz))
        sampleCount = rawSamples.count
        
        // 每50个样本打印一次确认
        if sampleCount % 50 == 0 {
            print("📊 已采集 \(sampleCount) 个样本 | 加速度: (\(String(format: "%.3f", ax)), \(String(format: "%.3f", ay)), \(String(format: "%.3f", az))) | 陀螺仪: (\(String(format: "%.3f", wx)), \(String(format: "%.3f", wy)), \(String(format: "%.3f", wz)))")
        }
        
        // 保存线性加速度（已经去除重力）
        let R = motion.attitude.rotationMatrix
        // transform device->earth frame: world = R * device
        let axw = R.m11 * userAcc.x + R.m12 * userAcc.y + R.m13 * userAcc.z
        let ayw = R.m21 * userAcc.x + R.m22 * userAcc.y + R.m23 * userAcc.z
        let azw = R.m31 * userAcc.x + R.m32 * userAcc.y + R.m33 * userAcc.z
        linSamples.append(LinSample(t: now, ax_lin: axw, ay_lin: ayw, az_lin: azw))
    }
    
    // MARK: - Export CSV (Excel compatible)
    @discardableResult
    func exportCSVs(userName: String, note: String) throws -> [URL] {
        let safeName = sanitize(fileSegment: userName)
        let safeNote = sanitize(fileSegment: note.isEmpty ? "未备注" : note)
        let rawFileName = "\(safeName)_\(safeNote)_1.csv"
        let linFileName = "\(safeName)_\(safeNote)_2.csv"
        
        let rawCSV = buildRawCSV()
        let linCSV = buildLinCSV()
        
        let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let rawURL = dir.appendingPathComponent(rawFileName)
        let linURL = dir.appendingPathComponent(linFileName)
        
        try rawCSV.data(using: .utf8)?.write(to: rawURL, options: .atomic)
        try linCSV.data(using: .utf8)?.write(to: linURL, options: .atomic)
        
        return [rawURL, linURL]
    }
    
    private func buildRawCSV() -> String {
        var s = "timestamp,ax,ay,az,wx,wy,wz\n"
        for r in rawSamples {
            s += String(format: "%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.6f\n", r.t, r.ax, r.ay, r.az, r.wx, r.wy, r.wz)
        }
        return s
    }
    
    private func buildLinCSV() -> String {
        var s = "timestamp,ax_lin,ay_lin,az_lin\n"
        for v in linSamples {
            s += String(format: "%.6f,%.6f,%.6f,%.6f\n", v.t, v.ax_lin, v.ay_lin, v.az_lin)
        }
        return s
    }
    
    private func sanitize(fileSegment: String) -> String {
        let illegal = CharacterSet(charactersIn: "/\\?%*|\"<>:")
        let cleaned = fileSegment.components(separatedBy: illegal).joined(separator: "_")
        return cleaned.replacingOccurrences(of: "\n", with: " ").replacingOccurrences(of: "\r", with: " ")
    }
}

// MARK: - CMHeadphoneMotionManagerDelegate
extension SensorRecorder: CMHeadphoneMotionManagerDelegate {
    func headphoneMotionManagerDidConnect(_ manager: CMHeadphoneMotionManager) {
        print("✅ AirPods 已连接")
        isHeadphoneConnected = true
    }
    
    func headphoneMotionManagerDidDisconnect(_ manager: CMHeadphoneMotionManager) {
        print("❌ AirPods 已断开")
        isHeadphoneConnected = false
    }
}
